#pragma once

#include "HashTable.h"
namespace Rustle
{
	template<class K, class Hash = HashFunc<K>>
	class unordered_set
	{
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
		typedef typename HashBucket::HashTable<K, const K, SetKeyOfT, Hash>::Iterator iterator;
		typedef typename HashBucket::HashTable<K, const K, SetKeyOfT, Hash>::ConstIterator const_iterator;

		iterator begin()
		{
			return _ht.Begin();
		}

		iterator end()
		{
			return _ht.End();
		}

		const_iterator begin() const
		{
			return _ht.Begin();
		}

		const_iterator end() const
		{
			return _ht.End();
		}

		pair<iterator, bool> insert(const K& kv)
		{
			return _ht.Insert(kv);
		}

		iterator Find(const K& key)
		{
			return _ht.Find(key);
		}

		bool Erase(const K& key)
		{
			return _ht.Erase(key);
		}

	private:
		HashBucket::HashTable<K, const K, SetKeyOfT, Hash> _ht;
	};

	void Print(const unordered_set<int>& s)
	{
		unordered_set<int>::const_iterator it = s.begin();
		while (it != s.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}

	struct Date
	{
		int _year;
		int _month;
		int _day;

		Date(int year, int month, int day)
			:_year(year)
			,_month(month)
			,_day(day)
		{}

		bool operator==(const Date& d) const
		{
			return _year == d._year
				&& _month == d._month
				&& _day == d._day;
		}
	};

	struct HashDate
	{
		size_t operator()(const Date& key)
		{
			return key._year * 10000 + key._month * 100 + key._day;
		}
	};

	void test_set()
	{
		unordered_set<Date, HashDate> us;
		us.insert({ 2024, 7, 28 });
		us.insert({ 2024, 7, 24 });
		us.insert({ 2024, 6, 28 });

		unordered_set<Date, HashDate>::iterator it = us.begin();
		while (it != us.end())
		{
			cout << it->_year << "/" << it->_month << "/" << it->_day << endl;
			++it;
		}
		cout << endl;

		unordered_set<int> s;
		int a[] = { 4,2,6,1,3,5,15,7,16,14 };
		for (auto e: a)
		{
			s.insert(e);
		}

		for (auto e : s)
		{
			cout << e << " ";
		}
		cout << endl;

		//unordered_set<int>::iterator it = s.begin();
		//while (it != s.end())
		//{
		//	cout << *it << " ";
		//	++it;
		//}
		//cout << endl;

		//Print(s);
	}
}